package ru.ipo.dces.client.messages;

import ru.ipo.dces.client.Controller;

import javax.swing.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.List;

public class PopupMessageManager {

    private int ANIMATION_TIME = 700;
    private int availableMessages;

    private Timer timer = new Timer(ANIMATION_TIME / PopupMessage.FRAMES, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            repaintAnimation();
        }
    });

    private JPanel glassPanel;

    /**
     * currently shown messages
     */
    private List<PopupMessage> messages = new LinkedList<PopupMessage>();

    /**
     * Creates popup manager
     *
     * @param basePanel a panel to draw messages on
     */
    public PopupMessageManager(JPanel basePanel) {
        glassPanel = basePanel;

        basePanel.setLayout(null);
        basePanel.setVisible(true);

        glassPanel.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                windowResized();
            }
        });
        windowResized();
    }

    private int getNextOffsetFromBottom() {
        int maxOffset = -1;

        for (PopupMessage message : messages) {
            int bottomOffset = message.getBottomOffset();
            if (bottomOffset > maxOffset)
                maxOffset = bottomOffset;
        }

        return maxOffset + 1;
    }

    public void showPopupMessage(String message, PopupMessageType messageType) {
        int nextOffset = getNextOffsetFromBottom();

        if (nextOffset >= availableMessages) {
            removeMessage(messages.get(0));
            nextOffset = getNextOffsetFromBottom();
        }

        PopupMessage msg = new PopupMessage(message, messageType, nextOffset, glassPanel);
        messages.add(msg);
        glassPanel.add(msg);
        if (!timer.isRunning())
            timer.start();
    }

    private void repaintAnimation() {
        /*//find and remove deleted messages
        LinkedList<PopupMessage> deletedMessages = new LinkedList<PopupMessage>();
        for (PopupMessage message : messages)
            if (message.isDeleted())
                deletedMessages.add(message);

        for (PopupMessage deletedMessage : deletedMessages)
            removeMessage(deletedMessage);*/

        //stop timer if there are no more messages
        if (messages.isEmpty()) {
            timer.stop();
            return;
        }

        //refresh all other messages
        for (PopupMessage message : messages) {
            if (!message.hasDrawn())
                message.refresh();
        }
    }

    private void windowResized() {
        availableMessages = (glassPanel.getHeight() - Controller.getClientDialog().getStatusBar().getHeight())
                / PopupMessage.MESSAGE_HEIGHT;

        int messagesToRemove = messages.size() - availableMessages;
        //remove all messages that are no more visible
        for (int i = 0; i < messagesToRemove; i++) {
            PopupMessage popupMessage = messages.get(i);
            removeMessage(popupMessage);
        }


        //refresh all messages
        for (PopupMessage message : messages)
            message.refresh();
    }

    private void removeMessage(PopupMessage message) {
        int index = message.getBottomOffset();
        messages.remove(message);
        glassPanel.remove(message);
        for (PopupMessage msg : messages)
            if (msg.getBottomOffset() > index) {
                msg.setBottomOffset(msg.getBottomOffset() - 1);
                msg.refresh();
            }

        glassPanel.validate();
        glassPanel.repaint();
    }

    public void removeOldestDrawnMessage() {
        if (messages.size() == 0)
            return;
        if (messages.get(0).hasDrawn())
            removeMessage(messages.get(0));
    }
}
